/**
 * Copyright (c) 2017 ucsmy.com, All rights reserved.
 */
package itsm.isperp.module.controller.api.wechat.v2;

import com.fr.fs.base.entity.Department;
import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.service.BaseService;
import itsm.isperp.framework.utils.HibernateUUIDGenerator;
import itsm.isperp.framework.utils.Pair;
import itsm.isperp.framework.web.request.JqGridFilterRuleOp;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.module.entity.app.AppDepartment;
import itsm.isperp.module.entity.app.AppUser;
import itsm.isperp.module.entity.incident.IcdIncident;
import itsm.isperp.module.entity.incident.IcdIncidentHandleProcess;
import itsm.isperp.module.service.app.AppDepartmentService;
import itsm.isperp.module.service.app.AppDictService;
import itsm.isperp.module.service.app.AppUserService;
import itsm.isperp.module.service.incident.IcdIncidentHandleProcessService;
import itsm.isperp.module.service.incident.IcdIncidentService;
import itsm.isperp.module.utils.ProjectDomainUtils;
import itsm.isperp.workflow.dto.BpmTransitionLine;
import itsm.isperp.workflow.service.BpmProcessRunService;
import itsm.isperp.workflow.utils.BpmConst;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.*;

/**
 * @Description:
 * @Author: legen
 * @Created Date: 2017-09-14-0014.
 * @LastModifyDate: 2017-09-14-0014.
 * @LastModifyBy: legen
 * @Version:
 */
@Controller
@RequestMapping("api/wechat/v2/incident")
public class IncidentController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(IncidentController.class);

    @Resource(name = "bpmProcessRunService")
    private BpmProcessRunService bpmProcessRunService;

    @Resource(name = "appUserService")
    private AppUserService appUserService;

    @Autowired
    private AppDictService appDictService;

    @Autowired
    private IcdIncidentService icdIncidentService;

    @Autowired
    private AppDepartmentService appDepartmentService;

    /**
     * 事件申报
     */
    @RequestMapping(value = "new", method = RequestMethod.POST)
    @ResponseBody
    public void newIncident(String username, @RequestBody BpmData<IcdIncident> bpmData)
            throws Exception {

        login(username);

        IcdIncident model = bpmData.getData();
        model.setId(HibernateUUIDGenerator.generate());

        String userMobile = (String) bpmData.getOthers().get("userMobile");
        String userEmail = (String) bpmData.getOthers().get("userEmail");
        String linkmanName = (String) bpmData.getOthers().get("linkmanName");
        String userTel = (String) bpmData.getOthers().get("userTel");

        AppUser user = appUserService.findByUsername(model.getCusUserId());
        List<Map<String, Object>> projects = appUserService.findUserProjects(user.getId());
        if (projects != null && !projects.isEmpty()) {
            model.setProjectId(projects.get(0).get("id").toString());
        }
        model.setCusUserId(user.getId());
        if ("VIP".equals(user.getType())) {
            model.setAreVip(true);
        }

        // 本人
        if (user.getFullname().equals(linkmanName)) {

            model.setLinkmanName(user.getFullname());
            String userTel_ = StringUtils.isEmpty(userTel) ? "" : userTel + "/";
            model.setLinkmanPhone(userTel_ + userMobile);

            // 更新电话
            if (!StringUtils.isWhitespace(userMobile)) {

                user.setMobile(userMobile);
                if (StringUtils.isNotBlank(userEmail)) {
                    user.setEmail(userEmail);
                }
                if (StringUtils.isNotBlank(userTel)) {
                    user.setTel(userTel);
                }
                Set<String> columns = new HashSet<>();
                columns.add("mobile");
                columns.add("email");
                columns.add("tel");
                appUserService.dynamicUpdateSpecific(user, columns);
            }
        } else {

            model.setLinkmanName(linkmanName);
            String userTel_ = StringUtils.isEmpty(userTel) ? "" : userTel + "/";
            String userEmailt = StringUtils.isEmpty(userEmail) ? "" : "/" + userEmail;
            model.setLinkmanPhone(userTel_ + userMobile + userEmailt);
        }

        model.setSource("微信");
        model.setStatus(appDictService.getInitStatus("INCIDENT_STATUS"));

        icdIncidentService.saveOrUpdate(model);
        bpmProcessRunService.startProcess(username, INCIDENT_PROCESS, model.getId(), bpmData.getSuggestion());

        saveImages(model.getId(), bpmData.getImages());
        uploadPositionInfo(username, (String) bpmData.getOthers().get("longitude"), (String) bpmData.getOthers().get("latitude"));
    }
    
    @RequestMapping(value = "newIcd", method = RequestMethod.POST)
    @ResponseBody
    public void newIcd(String username, @RequestBody BpmData<IcdIncident> bpmData)
            throws Exception {

        login(username);

        IcdIncident model = bpmData.getData();
        model.setId(HibernateUUIDGenerator.generate());

        AppUser user = appUserService.findByUsername(username);
        List<Map<String, Object>> projects = appUserService.findUserProjects(user.getId());
        if (projects != null && !projects.isEmpty()) {
            model.setProjectId(projects.get(0).get("id").toString());
        }
        model.setCusUserId(user.getId());
        if ("VIP".equals(user.getType())) {
            model.setAreVip(true);
        }
        model.setSource("微信");
        model.setStatus(appDictService.getInitStatus("INCIDENT_STATUS"));

        icdIncidentService.saveOrUpdate(model);
        bpmProcessRunService.startProcess(username, INCIDENT_PROCESS, model.getId(), bpmData.getSuggestion());

        saveImages(model.getId(), bpmData.getImages());
        uploadPositionInfo(username, (String) bpmData.getOthers().get("longitude"), (String) bpmData.getOthers().get("latitude"));
    }

    /**
     * 查询事件数量
     */
    @RequestMapping("countByStatus")
    @ResponseBody
    public List<Map<String, Object>> countByStatus(String username) throws Exception {
        try {

            JqGridRequest request = new JqGridRequest();
            request.setSelectColumns("COUNT(*) count", "status", "CASE status WHEN '待分派' THEN 0 WHEN '待处理' THEN 1 WHEN '待响应' THEN 2 WHEN '待回访' THEN 3 WHEN '挂起中' THEN 4 END order_no");
            request.setSearchString(BpmConst.getQueryTaskSqlCondition(INCIDENT_PROCESS, "'" + username + "'") + " and status in('待分派','待处理','待响应','待回访','挂起中')");
            request.setGroupBy("status");
            request.setSort("order_no", Sort.Direction.ASC);

            List<Map<String, Object>> incidentCount = icdIncidentService.findAllDetailByRequest(request);
            return incidentCount;

        } catch (Exception e) {

            logger.error(e.getMessage(), e);
            throw new Exception("查询事件数量失败，原因是：" + e.getMessage());
        }
    }

    /**
     * 查询事件
     */
    @RequestMapping("listByStatus")
    @ResponseBody
    public List<Map<String, Object>> listByStatus(String username, String status)
            throws Exception {
        try {

            JqGridRequest request = new JqGridRequest();
            request.setPageable(false);
            request.setSelectColumns("id", "title", "create_date", "incident_type", "cus_customer_name", "status");
            request.setSort("create_date", Sort.Direction.ASC);
            request.setSearchString(BpmConst.getQueryTaskSqlCondition(INCIDENT_PROCESS, "'" + username + "'") + " and status = '" + status + "'");

            List<Map<String, Object>> list = icdIncidentService.findAllDetailByRequest(request).getContent();
            super.addNullColumns(request, list);
            return list;

        } catch (Exception e) {

            logger.error(e.getMessage(), e);
            throw new Exception("查询事件失败，原因是：" + e.getMessage());
        }
    }

    /**
     * 查询事件
     */
    @RequestMapping("query")
    @ResponseBody
    public List<Map<String, Object>> query(String username, String projectId, String content, String status, int top)
            throws Exception {
        try {

            JqGridRequest request = new JqGridRequest();
            if (top > 0) {
                request.setRows(top);
                request.setPageable(true);
            } else {
                request.setPageable(false);
            }
            request.setSelectColumns("id", "title", "create_date", "incident_type", "cus_customer_name", "status");
            request.setSort("create_date", Sort.Direction.DESC);
            String filter1 = ProjectDomainUtils.getUserDomainSqlForWechat(username, "project_id");

            String filter = " (1=1 " + filter1 + ") and (code='" + content + "' or title like '%" + content + "%' or description like '%" + content + "%')";
            if (StringUtils.isNotBlank(status)) {
                filter += " and status='" + status + "'";
            }
            if (StringUtils.isNotBlank(projectId)) {
                filter += " and project_id = '" + projectId + "'";
            }
            request.setSearchString(filter);
            List<Map<String, Object>> list = icdIncidentService.findAllDetailByRequest(request).getContent();
            super.addNullColumns(request, list);
            return list;

        } catch (Exception e) {

            logger.error(e.getMessage(), e);
            throw new Exception("查询事件失败，原因是：" + e.getMessage());
        }
    }

    /**
     * 事件明细
     */
    @RequestMapping("detail")
    @ResponseBody
    public Map<String, Object> detail(String username, String id)
            throws Exception {
        try {

            JqGridRequest request = new JqGridRequest();
            request.setSelectColumns(
                    "id", "process_id",
                    "code", "title", "description", "status",
                    "cus_user_id", "cus_user_name", "cus_user_type", "cus_customer_name", "department_id", "cus_email", "mobile", "linkman_name", "linkman_phone",
                    "source", "create_date", "incident_type", "happen_time", "occurrence_frequency", "expect_time",
                    "service_category_id", "service_category_name", "project_id", "project_name",
                    "assigner_name", "icd_category_id", "icd_category_name", "supporter_id", "supporter_name", "priority_name", "urgency_name", "effect_name",
                    "deal_type", "faultlocation_name", "reason_analyze", "solution", "handle_process",
                    "solver_id", "solver_name", "solved_date", "solution_way", "solution_stage",
                    "close_code", "satisfaction", "closed_date", "customer_opinion", "are_feedback","address"
            );
            request.addFilterRule("id", JqGridFilterRuleOp.eq, id);
            Map<String, Object> map = icdIncidentService.findOneDetailByRequest(request);

            if (map != null) {

                map.put("department_name", null);
                if (map.containsKey("department_id")) {
                    AppDepartment department = appDepartmentService.findOne(map.get("department_id").toString());
                    if (department != null) {
                        map.put("department_name", department.getName());
                    }
                }

                List<BpmTransitionLine> bpmTransitionLines = bpmProcessRunService.getNextSteps(INCIDENT_PROCESS, (String) map.get("process_id"), username);
                map.put("lines", bpmTransitionLines);
                super.addNullColumns(request, map);
                return map;

            } else {

                throw new Exception("该事件已删除!");
            }
        } catch (Exception e) {

            logger.error(e.getMessage(), e);
            throw new Exception("获取事件详情失败，原因是：" + e.getMessage());
        }
    }

    /**
     * 历史事件
     */
    @RequestMapping("history")
    @ResponseBody
    public List<Map<String, Object>> history(String username, String cus_user_id) throws Exception {
        try {
            JqGridRequest request = new JqGridRequest();
            request.setSelectColumns("id",
                    "status", "title", "create_date", "description",
                    "cus_user_name", "code",
                    "reason_analyze", "solution", "solved_date", "solver_name");
            request.addFilterRule("cus_user_id", JqGridFilterRuleOp.eq, cus_user_id);
            request.addFilterRule("status", JqGridFilterRuleOp.in, "'待分派','已关闭'");
            List<Map<String, Object>> map = icdIncidentService.findAllDetailByRequest(request);

            super.addNullColumns(request, map);
            return map;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new Exception("获取历史事件失败，原因是：" + e.getMessage());
        }
    }

    @RequestMapping(value = "submit", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> submit(String username, @RequestBody BpmData<IcdIncident> model)
            throws Exception {

        login(username);

        this.icdIncidentService.saveOrUpdateSpecific(model.getData(), model.getColumns());
        IcdIncident icdIncident = model.getData();
        BpmTransitionLine line = model.getLine();

        Pair<String, List<Map<String, Object>>> result = this.bpmProcessRunService
                .gotoNextSetp(
                        username,
                        INCIDENT_PROCESS,
                        line.getNextTaskId(),
                        line.getNextTransitionId(),
                        line.getProcessInstanceId(),
                        icdIncident.getId(),
                        model.getNextAssigner(),
                        model.getSuggestion(),
                        line.getProcessMode(),
                        line.getCommitType());

        saveImages(icdIncident.getId(), model.getImages());
        uploadPositionInfo(username, (String) model.getOthers().get("longitude"), (String) model.getOthers().get("latitude"));

        Map<String, Object> nextStep = new HashMap<>();
        if (result == null || result.getRightObject() == null || result.getRightObject().size() == 0) {
            nextStep.put("message", "流程结束");
            return nextStep;
        }

        StringBuilder nextUser = new StringBuilder();
        List<Map<String, Object>> list = result.getRightObject();
        int i = list.size();
        if (i > 0) {
            nextUser.append(list.get(0).get("fullname")).append("(").append(list.get(0).get("name")).append(")");
        }
        for (int j = 1; j < i; j++) {
            Map<String, Object> m = list.get(j);
            if (m != null) {
                nextUser.append(",").append(m.get("fullname")).append("(").append(m.get("name")).append(")");
            }
        }

        nextStep.put("message", result.getLeftObject() + "：" + nextUser.toString());

        return nextStep;
    }

    @Resource(name = "icdIncidentHandleProcessService")
    private IcdIncidentHandleProcessService icdIncidentHandleProcessService;

    @RequestMapping("handleProcess")
    @ResponseBody
    public List<IcdIncidentHandleProcess> handleProcess(String username, String id) {
        JqGridRequest req = new JqGridRequest();
        req.setSelectColumns("creator_name", "create_date", "reason_analyze", "solution", "handleProcess");
        req.isPageable(false);
        req.addFilterRule("relation_id", JqGridFilterRuleOp.eq, id);
        return icdIncidentHandleProcessService.findAll(req).getContent();

    }
    
    @RequestMapping("images")
    @ResponseBody
    public List<String> images(String username, String id) {
        return getImages(id);
    }

}